﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Design.Kernel.CAD;
using System.Drawing;

namespace DesignKernel.CAD
{
    public class TModel
    {
        public bool IsBoundDirty = false;
        Bound _bound = null;

        RenderSettings _renderSettings = new RenderSettings();

        /// <summary>
        /// Intenral triangle collection
        /// </summary>
        List<TTriangle> _triangles = new List<TTriangle>();


        /// <summary>
        /// True to show the model on the scene, False otherwise
        /// </summary>
        internal bool Visible { get; set; }
        

        /// <summary>
        /// Model name
        /// </summary>
        public string Name { get; set; }


        /// <summary>
        /// Model matrix
        /// </summary>
        public TMatrix Matrix { get; set; }


        public System.Drawing.Color MaterialColor { get; set; }


        /// <summary>
        /// Adds triangle to the model
        /// </summary>
        /// <param name="triangle"></param>
        public void AddTriangle(TTriangle triangle)
        {
            _triangles.Add(triangle);
        }



        public List<TTriangle> Triangles
        {
            get
            {
                return _triangles;
            }
        }


        public RenderSettings ModelRendetSettings
        {
            get
            {
                return _renderSettings;
            }
        }


        public Bound Bounds
        {
            get
            {
                if (_bound == null || IsBoundDirty)
                    _bound = GetModuleBounds();
                return _bound;
            }
        }


        private Bound GetModuleBounds()
        {
            Bound _bound = new Bound();
            double frontZ=1, backZ=-1;
            this.Triangles.ForEach((triangle) =>
            {
                TVertex v0 = triangle.Vertex0;
                TVertex v1 = triangle.Vertex1;
                TVertex v2 = triangle.Vertex2;

                //v0
                if (_bound.FrontTopLeft.x > v0.x)
                    _bound.FrontTopLeft.x = v0.x;
                if (_bound.FrontTopLeft.y < v0.y)
                    _bound.FrontTopLeft.y = v0.y;
                if (v0.z > frontZ)
                    frontZ = v0.z;
                if (v0.z < backZ)
                    backZ = v0.z;
                
                //v1
                if (_bound.FrontTopLeft.x > v1.x)
                    _bound.FrontTopLeft.x = v1.x;
                if (_bound.FrontTopLeft.y < v1.y)
                    _bound.FrontTopLeft.y = v1.y;
                if (v1.z > frontZ)
                    frontZ = v1.z;
                if (v1.z < backZ)
                    backZ = v1.z;

                //v2
                if (_bound.FrontTopLeft.x > v2.x)
                    _bound.FrontTopLeft.x = v2.x;
                if (_bound.FrontTopLeft.y < v2.y)
                    _bound.FrontTopLeft.y = v2.y;
                if (v2.z > frontZ)
                    frontZ = v2.z;
                if (v2.z < backZ)
                    backZ = v2.z;


                //v0
                if (_bound.FrontRightDown.x < v0.x)
                    _bound.FrontRightDown.x = v0.x;
                if (_bound.FrontRightDown.y > v0.y)
                    _bound.FrontRightDown.y = v0.y;

                //v1
                if (_bound.FrontRightDown.x < v1.x)
                    _bound.FrontRightDown.x = v1.x;
                if (_bound.FrontRightDown.y > v1.y)
                    _bound.FrontRightDown.y = v1.y;

                //v2
                if (_bound.FrontRightDown.x < v2.x)
                    _bound.FrontRightDown.x = v2.x;
                if (_bound.FrontRightDown.y > v2.y)
                    _bound.FrontRightDown.y = v2.y;

            });

            _bound.Deepness = frontZ - backZ;
            return _bound;
        }

    }
}
